package platformlog_logic

import (
	"context"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/sqlx"

	"yunzhan/api-server/internal/svc"
	"yunzhan/api-server/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type AddComponentInfoLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// NewAddComponentInfoLogic 新增组件信息
func NewAddComponentInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddComponentInfoLogic {
	return &AddComponentInfoLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *AddComponentInfoLogic) AddComponentInfo(req *types.AddComponentInfoRequest) (resp *types.AddComponentInfoResponse, err error) {
	flag := l.svcCtx.Config.UseMysql

	var insertSQL string
	tableName := l.svcCtx.Config.SQLite.Tables.ComponentInfo
	if flag {
		tableName = l.svcCtx.Config.Mysql.Tables.ComponentInfo
	}

	if flag {
		insertSQL = fmt.Sprintf(`
		INSERT INTO %s (cluster_id, component_name, version, node_host, node_ip, component_role, home_path, data_storage_dir, port, status, additional_info)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON DUPLICATE KEY UPDATE
		    cluster_id=VALUES(cluster_id),
			version=VALUES(version),
			component_role=VALUES(component_role),
			home_path=VALUES(home_path),
			data_storage_dir=VALUES(data_storage_dir),
			port=VALUES(port),
			status=VALUES(status),
			additional_info=VALUES(additional_info),
			updated_at=CURRENT_TIMESTAMP(3);`, tableName)
	} else {
		insertSQL = fmt.Sprintf(`
		INSERT INTO %s (cluster_id, component_name, version, node_host, node_ip, component_role, home_path, data_storage_dir, port, status, additional_info)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
		ON CONFLICT(cluster_id,component_name,version,node_ip,port) DO UPDATE SET
			cluster_id=excluded.cluster_id,
			version=excluded.version,
			component_role=excluded.component_role,
			home_path=excluded.home_path,
			data_storage_dir=excluded.data_storage_dir,
			port=excluded.port,
			status=excluded.status,
			additional_info=excluded.additional_info,
			updated_at=CURRENT_TIMESTAMP(3);`, tableName)
	}

	err = l.svcCtx.Conn.TransactCtx(context.Background(), func(ctx context.Context, sess sqlx.Session) error {
		for _, info := range req.ComponentInfos {
			_, err = sess.ExecCtx(ctx, insertSQL, info.ClusterID, info.ComponentName, info.Version, info.NodeHost, info.NodeIP, info.ComponentRole, info.HomePath, info.DataStorageDir, info.Port, info.Status, info.AdditionalInfo)
			if err != nil {
				logx.Errorf("failed to execute insert: %v", err)
				return err
			}
		}
		return nil
	})

	if err != nil {
		logx.Errorf("failed to add component info: %v", err)
		return nil, err
	}

	return &types.AddComponentInfoResponse{
		Code:    200,
		Message: "组件信息写入完成",
		Data:    req.ComponentInfos,
	}, nil
}
